﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ObligatorioBD.MerObjects;

namespace ObligatorioBD
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

#region Event Methods
        
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            CargarMer();
            //FormSelector f = new FormSelector();
            //f.ShowDialog();
        }

        private void tsbConfigureConnection_Click(object sender, EventArgs e)
        {
            ConfConnection();
        }

        private void cargarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CargarMer();
        }
        
        private void normalizarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Mer m = GetSelectedMer();
            if (m != null)
            {
                Normalize();
            }
            else
            {
                MessageBox.Show("Se debe seleccionar el nodo principal");
            }
        }

        private void tsbNormalize_Click(object sender, EventArgs e)
        {
            Mer m = GetSelectedMer();
            if (m != null)
            {
                Normalize();
            }
            else
            {
                MessageBox.Show("Se debe seleccionar el nodo principal");
            }
        }
        
        private void LoadGrid()
        { }
        
        private void frmMain_Load(object sender, EventArgs e)
        {
            LoadData();
        }

        private void tsbReload_Click(object sender, EventArgs e)
        {
            LoadData();
        }

        private void grdList_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {

        }
        
        private void normalizarToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            Mer m = GetSelectedMer();
            if (m != null)
            {
                Normalize();
            }
            else
            {
                MessageBox.Show("Se debe seleccionar el nodo principal");
            }
        }

        private void crearBaseDeDatosToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            CreateDataBase();
        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {

        }

        private void normalizarToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Normalize();
        }

        private void crearBaseDeDatosToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDataBase();
        }

        private void eliminarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DeleteMer();
        }

        private void LoadData()
        {
            try
            {
                this.treeView.Nodes.Clear();
                Logic.GeneralData gData = new Logic.GeneralData(new DatabaseInterface.Connection());
                List<MerObjects.Mer> merList = gData.GetMerList();
                MerDataSet ds = new MerDataSet();
                LoadTree(merList);
                foreach (MerObjects.Mer m in merList)
                {
                    ds.Mer.AddMerRow(m.ObjectId, m.Name, m.Owner);
                }
                this.grdList.DataSource = ds.Mer;
                this.grdList.Refresh();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void LoadTree(List<MerObjects.Mer> merList)
        {
            TreeNode merNode;
            TreeNode entitiesNode;
            TreeNode entityNode;
            TreeNode relationNode;
            TreeNode relationsNode;
            foreach (MerObjects.Mer m in merList)
            {
                merNode = new TreeNode(m.Name);
                merNode.StateImageIndex = 0;
                merNode.Tag = m;
                entitiesNode = new TreeNode("Entidades");
                entitiesNode.Tag = m.GetEntities();
                merNode.Nodes.Add(entitiesNode);
                foreach (Entity e in m.GetEntities())
                {
                    entityNode = new TreeNode(e.Name);
                    entityNode.Tag = e;
                    entityNode.Nodes.Add(ProcessAtibutes(e));
                    entitiesNode.Nodes.Add(entityNode);
                }
                relationsNode = new TreeNode("Relaciones");
                merNode.Nodes.Add(relationsNode);
                relationsNode.Tag = m.GetRelations();
                foreach (Relationship r in m.GetRelations())
                {
                    relationNode = new TreeNode(r.Name);
                    relationNode.Tag = r;
                    relationNode.Nodes.Add(ProcessAtibutes(r));
                    relationsNode.Nodes.Add(relationNode);
                    entitiesNode = new TreeNode("Entidades");
                    entitiesNode.Tag = r.GetEntities();
                    foreach (CardinalEntity ce in r.GetEntities())
                    {
                        entityNode = new TreeNode(ce.Entity.Name + " (" + ce.Cardinality + ")");
                        entityNode.Tag = ce;
                        entitiesNode.Nodes.Add(entityNode);
                    }
                    relationNode.Nodes.Add(entitiesNode);

                }
                this.treeView.Nodes.Add(merNode);
            }

        }
        
        private TreeNode ProcessAtibutes(IAtributeObject obj)
        {
            TreeNode atributeNode;
            TreeNode atributesNode = new TreeNode("Atributos");
            atributesNode.Tag = obj.GetAtributes();
            foreach (Atribute a in obj.GetAtributes())
            {
                atributeNode = new TreeNode(a.ToString());
                atributeNode.Tag = a;
                if (a.Type == Atribute.AtributeType.CompositeType)
                {
                    atributeNode.Nodes.Add(ProcessAtibutes(a));
                }
                if (a.IsPrimaryKey)
                {
                    atributeNode.StateImageIndex = 1;
                }
                atributesNode.Nodes.Add(atributeNode);
            }
            return atributesNode;
        }

#endregion


        #region Common Methods

        private void CargarMer()
        {
            FormSelector f = new FormSelector();
            f.ShowDialog();
            Reload();
        }
        private void Reload()
        {
            LoadData();
        }
        private Mer GetSelectedMer()
        {
            Mer mer = null;
            TreeNode node = this.treeView.SelectedNode;
            while (node != null)
            {
                if (node.Tag is Mer)
                {
                    mer = (Mer)node.Tag;
                    node = null;
                }
                else
                {
                    node = node.Parent;
                }
            }
            return mer;
        }
        
        private void CreateDataBase()
        {
            frmNewDatabase f = new frmNewDatabase(GetSelectedMer());
            f.ShowDialog();
        }

        private void Normalize()
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                Logic.Normalize norma = new Logic.Normalize();
                Mer normalized = norma.Form1(GetSelectedMer());
                Logic.MerPersistor persistor = new Logic.MerPersistor();
                normalized.Name = normalized.Name + "_Normalizado";
                persistor.PersistMer(normalized);
            }
            catch
            {
                MessageBox.Show("Error al normalizar");
            }
            this.Cursor = Cursors.Default;
            Reload();
        }

        private void ConfConnection()
        {
            DatabaseInterface.ConfigureConnection conf = new DatabaseInterface.ConfigureConnection();
            conf.ShowDialog();
        }

        private void DeleteMer()
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                Mer m = GetSelectedMer();
                m.Delete();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            this.Cursor = Cursors.Default;
            Reload();
        }

        private void tsbHelp_Click(object sender, EventArgs e)
        {
            help();
        }

        private void help()
        {
            frmUsing help = new frmUsing();
            help.ShowDialog();
        }

        #endregion

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmAbout f = new frmAbout();
            f.ShowDialog();
        }

        private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            object o = null;
            TreeNode node = this.treeView.SelectedNode;
            o = node.Tag;
            string nodo = "";
            if (o is Mer)
            {
                LoadMerInfo((Mer)o);
            }
            else if (o is Entity)
            {
                LoadAtributeDataGrid(((Entity)o).GetAtributes());
            }
            else if (o is Relationship)
            {
                LoadCardinalEntity(((Relationship)o).GetEntities());
            }
            else if (o is List<Entity>)
            {
                LoadEntityDataGrid((List<Entity>)o);
            }
            else if (o is List<Relationship>)
            {
                LoadRelationDataGrid((List<Relationship>)o);
            }
            else if (o is Atribute)
            {
                nodo = "Atributo";
            }
            else if (o is List<Atribute>)
            {
                LoadAtributeDataGrid((List<Atribute>)o);
            }
            //MessageBox.Show(nodo);
        }
        private void LoadMerInfo(Mer mer)
        {
            MerDataSet ds = new MerDataSet();
            ds.Mer.AddMerRow(mer.ObjectId, mer.Name, mer.Owner);
            this.grdList.DataSource = ds.Mer;
            this.grdList.Refresh();
        }
        private void LoadCardinalEntity(List<CardinalEntity> entidades)
        {
            MerDataSet ds = new MerDataSet();
            int merId = GetSelectedMer().ObjectId;
            Entity e;
            foreach (CardinalEntity ce in entidades)
            {
                e = ce.Entity;
                ds.Entity.AddEntityRow(merId, e.ObjectId, e.Name, e.IsWeak);
            }
            this.grdList.DataSource = ds.Entity;
            this.grdList.Refresh();
        }
        private void LoadAtributeDataGrid(List<Atribute> atributos)
        {
            MerDataSet ds = new MerDataSet();
            foreach (Atribute a in atributos)
            {
                ds.Atributes.AddAtributesRow(a.ObjectId, a.Name, a.Type.ToString(), a.IsPrimaryKey, a.Cantidad);
            }
            this.grdList.DataSource = ds.Atributes;
            this.grdList.Refresh();

        }
        private void LoadEntityDataGrid(List<Entity> entidades)
        {
            MerDataSet ds = new MerDataSet();
            int merId = GetSelectedMer().ObjectId;
            foreach (Entity e in entidades)
            {
                ds.Entity.AddEntityRow(merId, e.ObjectId, e.Name, e.IsWeak);
            }
            this.grdList.DataSource = ds.Entity;
            this.grdList.Refresh();

        }
        private void LoadRelationDataGrid(List<Relationship> relaciones)
        {
            MerDataSet ds = new MerDataSet();
            int merId = GetSelectedMer().ObjectId;
            foreach (Relationship r in relaciones)
            {
                ds.Relation.AddRelationRow(merId, r.ObjectId, r.Name);
            }
            this.grdList.DataSource = ds.Relation;
            this.grdList.Refresh();

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void connectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfConnection();
        }


    }
}
